<template>
  <basic-dialog
    title="关联商品"
    width="60%"
    :visible="dialogVisible"
    :showFooter="false"
    :handleClose="handleClose"
  >
    <el-form
      v-show="isNotLinkedForState()"
      ref="formData"
      :model="formData"
      label-width="100px"
      inline
    >
      <el-form-item prop="brandName" label="品牌名称">
        <el-input v-model="formData.brandName"></el-input>
      </el-form-item>
      <el-form-item prop="brandEnName" label="品牌英文名称">
        <el-input v-model="formData.brandEnName"></el-input>
      </el-form-item>
    </el-form>
    <el-row type="flex" justify="end">
      <el-button
        v-show="isNotLinkedForState()"
        type="primary"
        @click="handleQuery"
      >查询</el-button
      >
      <el-button
        v-show="isNotLinkedForState()"
        @click="handleReset"
      >清空</el-button
      >
      <el-button
        type="primary"
        v-show="isNotLinkedForState()"
        @click="handleBatchLinked"
      >批量关联</el-button
      >
      <el-button
        v-show="isLinkedForState()"
        @click="handleBatchAbandonLinked"
      >批量取消</el-button
      >
      <el-button type="primary" @click="handleOk">确定</el-button>
    </el-row>
    <el-tabs v-model="tabs.current" @tab-click="handleSwitchTabs">
      <el-tab-pane label="已关联" :name="tabs.nameList[1]"></el-tab-pane>
      <el-tab-pane label="未关联" :name="tabs.nameList[0]"></el-tab-pane>
    </el-tabs>
    <el-row>
      <SkusTable
        ref="skusTable"
        showActionCol
        showSelectCol
        :showPagination="isNotLinkedForState()"
        :loading="tableInfo.loading"
        :columns="tableInfo.columns"
        :dataSource="tableInfo.list"
        :pagination="pagination"
        :total="pagination.total"
        :actionRender="renderTableAction"
        :selectionChange="handleSelectionChange"
        :pageSizes="[10, 20, 30, 40]"
        @pageChange="handlePageChange"
        @pageSizeSelect="handlePageSizeChange"
        @handleRowChange="handleChangeNumInput"
      />
    </el-row>
  </basic-dialog>
</template>
<script>
import { ApiRequest } from '@api/basePage';
import { mapState, mapMutations } from 'vuex';
import BasicDialog from '@/components/BasicDialog';
import SkusTable from '@/components/skusTable';
import { isResponseSuccess } from '@/utils/bizUtils';
import { getTableColumns } from './tableColumns';
import { getArraysByMaps } from '@/utils/getUtils';
export default {
  components: {
    BasicDialog,
    SkusTable
  },
  props: {
    visible: {
      type: Boolean,
      required: true
    },
  },
  data () {
    return {
      dialogVisible: false,
      formData: {
        brandName: '', // 品牌名称
        brandEnName: '', // 品牌英文名称
      },
      tabs: {
        current: 'linked', // 当前tabs页签
        nameList: ['notLinked', 'linked'] // tabs页签key集合
      },
      tableInfo: {
        list: [],
        selection: [],
        loading: false,
        columns: [],
        listCached: new Map(),
      },
      pagination: {
        pageNum: 1, // 当前页码
        pageSize: 10, // 每页条数
        total: 0 // 总条数
      },
      apiObj: {
        getBrandNotRelByCondition: { // 品牌未关联列表
          url: '/sysback/productbrand/productbrand/getBrandNotRelByCondition',
          type: 'post' // 接口请求类型
        },
        getBrandRelByCondition: { // 品牌已关联列表
          url: '/sysback/productbrand/productbrand/getBrandRelByCondition',
          type: 'post' // 接口请求类型
        },
      },
      originalLinkedMaps: new Map() // 初次进入弹窗的已关联数据
    }
  },
  destroyed () {
    this.CLEAR_BRANDS();
    this.CLEAR_UUIDS();
  },
  computed: {
    ...mapState('commonComps/linkBrands', ['cacheBrands', 'brandUuids']),
  },
  watch: {
    visible (val) {
      this.dialogVisible = val;
      if (!val) { return; }
      this.tableInfo.columns = getTableColumns(this.tabs);
      this.loadLinkedBrands();
    }
  },
  methods: {
    ...mapMutations(
      'commonComps/linkBrands',
      [
        'INIT_BRANDS', 'LINK_BRANDS', 'CANCEL_BRANDS',
        'BATCH_LINK_BRANDS', 'BATCH_CANCEL_BRANDS',
        'ADD_UUID', 'REMOVE_UUID', 'BANTCH_ADD_UUID',
        'BATCH_REMOVE_UUID', 'CLEAR_BRANDS', 'CLEAR_UUIDS'
      ]
    ),
    // 表格操作列按钮渲染
    renderTableAction (h, { row, index }) {
      const mappings = {
        [this.tabs.nameList[0]]: {
          label: '关联',
          methodFn: this.handleLinked
        },
        [this.tabs.nameList[1]]: {
          label: '取消',
          methodFn: this.handleCanceled
        }
      }
      const current = mappings[this.tabs.current];
      if (!current) { return <div></div> }
      return <div class="table-action">
        {
          <el-button
            size="mini"
            type="text"
            onClick={() => current.methodFn(row, index)}
          >{ current.label }
          </el-button>
        }
      </div>;
    },
    // 是未关联
    isNotLinkedForState () {
      return this.tabs.current === this.tabs.nameList[0];
    },
    // 是已关联
    isLinkedForState () {
      return this.tabs.current === this.tabs.nameList[1];
    },
    // 表格勾选为空
    isEmptyForSelection () {
      const isEmpty = this.tableInfo.selection.length === 0;
      if (isEmpty) {
        this.$message.warning('请勾选表格后再操作');
      }
      return isEmpty;
    },
    // 关联品牌缓存为空
    isEmptyForLinkedCache () {
      return this.cacheBrands.size === 0;
    },
    // 初始已关联品牌为空
    isEmptyForInitBrandsLinked () {
      return this.brandUuids.size === 0;
    },
    // 表格数据为空
    isEmptyForTableData () {
      return this.tableInfo.list === 0;
    },
    // 售价指导加价率和成交最低加价率为空（已关联品牌加价率必填,且都必须大于0）
    isEmptyForAddRate (data) {
      return data.some(item => !item.guideAddRate || !item.limitAddRate);
    },
    // 成交最低加价率大于售价指导加价率（成交最低加价率需小于等于售价指导加价率）
    isLimitMoreThanGuide (data) {
      return data.some(item => item.limitAddRate > item.guideAddRate);
    },
    // 确定提交
    handleOk () {
      const linkedTableList = getArraysByMaps(this.cacheBrands);
      if (this.isEmptyForAddRate(linkedTableList)) {
        this.$message.warning('请确保售价指导加价率、成交最低加价率填写完整且均大于0');
        return;
      }
      if (this.isLimitMoreThanGuide(linkedTableList)) {
        this.$message.warning('成交最低加价率不能大于售价指导加价率');
        return;
      }
      this.$emit('getLinkedBrandsInfo', this.getLinkedBrandsInfo());
      this.$emit('update:visible', false);
      this.clearDataStatus();
    },
    // 关闭弹框
    handleClose () {
      this.resetTabsState(); // tabs状态重置
      this.$emit('update:visible', false);
    },
    // 切换tabs
    handleSwitchTabs () {
      this.tableInfo.columns = getTableColumns(this.tabs);
      if (this.isLinkedForState()) {
        this.loadLinkedBrands();
      }
      if (this.isNotLinkedForState()) {
        this.loadNotLinkedBrands();
      }
    },
    // 查询
    handleQuery () {
      this.pagination.pageNum = 1;
      this.loadNotLinkedBrands();
    },
    // 清空
    handleReset () {
      this.$refs['formData'].resetFields();
    },
    // 关联
    handleLinked (row, index) {
      this.LINK_BRANDS(row);
      this.ADD_UUID(row.uuid);
      this.spliceTableInfoList(index);
      this.loadNotLinkedBrands();
      this.$message.success('关联成功');
    },
    // 取消关联
    handleCanceled (row, index) {
      this.CANCEL_BRANDS(row);
      this.REMOVE_UUID(row.uuid);
      this.spliceTableInfoList(index);
      this.$message.success('取消成功');
    },
    // 批量关联
    handleBatchLinked () {
      if (this.isEmptyForSelection()) { return; }
      const uuids = this.tableInfo.selection.map(item => item.uuid);
      this.BATCH_LINK_BRANDS(this.tableInfo.selection);
      this.BANTCH_ADD_UUID(uuids);
      this.spliceTableInfoList(uuids);
      this.loadNotLinkedBrands();
      this.$message.success('批量关联成功');
    },
    // 批量取消
    handleBatchAbandonLinked () {
      if (this.isEmptyForSelection()) { return; }
      const uuids = this.tableInfo.selection.map(item => item.uuid);
      this.BATCH_CANCEL_BRANDS(this.tableInfo.selection);
      this.BATCH_REMOVE_UUID(uuids);
      this.spliceTableInfoList(uuids);
      this.$message.success('批量取消成功');
    },
    // 表格数值输入框change事件
    handleChangeNumInput (row) {
      this.LINK_BRANDS(row);
    },
    // 表格数据勾选或勾选取消
    handleSelectionChange (list) {
      this.tableInfo.selection = list;
    },
    // 改变页码
    handlePageChange (currentPage) {
      this.pagination.pageNum = currentPage;
      this.loadNotLinkedBrands(); // 重新加载表格数据
    },
    // 改变当前页条数大小
    handlePageSizeChange (pageSize) {
      this.pagination.pageSize = pageSize;
      if (this.isEmptyForTableData()) { return; }
      this.loadNotLinkedBrands(); // 重新加载表格数据
    },
    /**
     * 根据pagesource获取uuid入参
     * @pagesource 1-重新提交；2-编辑
    */
    getUuidParamByPagesource () {
      if (this.$attrs.pagesource == 1) {
        return { aduitCategoryUuid: this.$attrs.uuid };
      }
      if (this.$attrs.pagesource == 2) {
        return { categoryUuid: this.$attrs.uuid }
      }
    },
    // 加载已关联品牌数据
    loadLinkedBrands () {
      if (this.isEmptyForInitBrandsLinked()) {
        this.tableInfo.list = [];
        return;
      }
      const disabledRowValidate = item => {
        const HasAddRateVal = !!(item.guideAddRate && item.limitAddRate)
        const GuideGreaterLimit = item.guideAddRate >= item.limitAddRate
        return HasAddRateVal && GuideGreaterLimit
      }
      this.postRequestTableData({
        ...this.apiObj.getBrandRelByCondition,
        data: {
          ...this.getParamsByRequestTableData(),
          ...this.getUuidParamByPagesource(),
          pageShow: 1000
        }
      }).then(retData => {
        if (retData) {
          if (this.isEmptyForLinkedCache()) {
            this.INIT_BRANDS(retData.results
              .map(item => [item.uuid, { ...item, inputDisabled: disabledRowValidate(item) }])
            );
          }
          this.tableInfo.list = getArraysByMaps(this.cacheBrands);
          this.reloadTableLayout();
        }
      });
    },
    // 加载未关联品牌数据
    loadNotLinkedBrands () {
      this.postRequestTableData({
        ...this.apiObj.getBrandNotRelByCondition,
        data: { ...this.getParamsByRequestTableData(), pageShow: this.pagination.pageSize }
      }).then(retData => {
        if (retData) {
          this.tableInfo.list = retData.results || [];
          this.pagination.total = retData.totalNum;
          this.reloadTableLayout();
        }
      });
    },
    // 表格DOM重新渲染
    reloadTableLayout () {
      this.$nextTick(() => {
        this.$refs.skusTable.$refs.plTable.doLayout();
      });
    },
    // 获取表格数据请求入参
    getParamsByRequestTableData () {
      const relBrandUuids = [...this.brandUuids];
      const { brandName, brandEnName } = this.formData;
      const data = {
        brandName,
        brandEnName,
        relBrandUuids,
        nowPage: this.pagination.pageNum,
        sortName: '',
        sortType: ''
      }
      return data;
    },
    // 获取关联品牌预提交的相关信息
    getLinkedBrandsInfo () {
      const result = getArraysByMaps(this.cacheBrands);
      let brandNames = [];
      let brandUuids = [];
      const categoryBrandRelList = result.reduce((value, item) => {
        brandNames.push(item.brandName);
        brandUuids.push(item.uuid);
        value.push({
          brandUuid: item.uuid,
          guideAddRate: item.guideAddRate,
          limitAddRate: item.limitAddRate
        });
        return value;
      }, []);
      return {
        brandUuids,
        brandNames: brandNames.join(';'),
        categoryBrandRelList
      }
    },
    // 重置tabs页签状态
    resetTabsState () {
      this.tabs.current = this.tabs.nameList[1]; // tabs状态重置
    },
    // 清空状态
    clearDataStatus () {
      this.resetTabsState(); // tabs状态重置
      this.handleReset(); // 表单清空
      this.tableInfo.list = []; // 表格清空
      this.tableInfo.selection = []; // 表格勾选清空
      this.pagination = {
        pageNum: 1, // 当前页码
        pageSize: 10, // 每页条数
        total: 0 // 总条数
      }
    },
    // 关联或取消关联去除对应表格数据
    spliceTableInfoList (val) {
      if (typeof val === 'number') {
        this.tableInfo.list.splice(val, 1);
      }
      if (Array.isArray(val)) {
        this.tableInfo.list = this.tableInfo.list.filter(row => !val.includes(row.uuid));
      }
    },
    // 获取表格数据post请求
    async postRequestTableData ({ url, type, data }) {
      try {
        this.tableInfo.loading = true;
        const res = await ApiRequest(url, type, data);
        this.tableInfo.loading = false;
        if (isResponseSuccess(res)) {
          return res.retData;
        }
        this.tableInfo.list = [];
      } catch (err) {
        this.tableInfo.list = [];
        this.tableInfo.loading = false;
      }
    },
  }
}
</script>
<style lang="less" scoped>
</style>
